import datetime
import logging
import os
from logging.handlers import RotatingFileHandler

from src.config.settings import LOG_FILE_NAME, LOG_LEVEL, LOGS_DIR


class LoggingUtils:
    """日志管理工具类"""

    def __init__(self, log_name="HY_PACKAGING_SYSTEM", log_dir=None):
        """初始化日志工具类

        Args:
            log_name: 日志名称
            log_dir: 日志文件目录
        """
        # 设置日志目录
        if log_dir is None:
            # 使用settings.py中的LOGS_DIR配置
            self.log_dir = os.path.join(
                os.path.dirname(
                    os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
                ),
                LOGS_DIR,
            )
        else:
            self.log_dir = log_dir

        # 确保日志目录存在
        if not os.path.exists(self.log_dir):
            os.makedirs(self.log_dir, exist_ok=True)

        # 创建日志器
        self.logger = logging.getLogger(log_name)

        # 设置日志级别
        log_level_map = {
            "DEBUG": logging.DEBUG,
            "INFO": logging.INFO,
            "WARNING": logging.WARNING,
            "ERROR": logging.ERROR,
            "CRITICAL": logging.CRITICAL,
        }
        self.logger.setLevel(log_level_map.get(LOG_LEVEL, logging.INFO))

        # 清空已有的处理器（防止重复添加）
        if self.logger.handlers:
            self.logger.handlers.clear()

        # 创建控制台处理器
        self._setup_console_handler()

        # 创建文件处理器
        self._setup_file_handler()

        # 格式化日志信息
        formatter = logging.Formatter(
            "%(asctime)s - %(name)s - %(levelname)s - %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
        )

        # 为所有处理器设置格式
        for handler in self.logger.handlers:
            handler.setFormatter(formatter)

        # 记录初始化信息
        self.info("日志工具初始化完成")

    def _setup_console_handler(self):
        """设置控制台日志处理器"""
        # 创建控制台处理器
        console_handler = logging.StreamHandler()

        # 设置控制台日志级别
        console_handler.setLevel(logging.INFO)  # 控制台默认使用INFO级别

        # 添加控制台处理器到日志器
        self.logger.addHandler(console_handler)

    def _setup_file_handler(self):
        """设置文件日志处理器"""
        # 获取当前日期作为日志文件名的一部分
        current_date = datetime.datetime.now().strftime("%Y%m%d")

        # 使用settings.py中的LOG_FILE_NAME作为基础文件名，添加日期后缀
        base_log_name = os.path.splitext(LOG_FILE_NAME)[0]
        log_file_name = f"{base_log_name}_{current_date}.log"

        # 日志文件完整路径
        log_file_path = os.path.join(self.log_dir, log_file_name)

        # 创建文件处理器，使用RotatingFileHandler支持日志轮转
        max_bytes = 10 * 1024 * 1024  # 10MB
        backup_count = 5  # 保留5个备份

        file_handler = RotatingFileHandler(
            log_file_path,
            maxBytes=max_bytes,
            backupCount=backup_count,
            encoding="utf-8",
        )

        # 设置文件日志级别
        file_handler.setLevel(logging.DEBUG)  # 文件日志默认使用DEBUG级别

        # 添加文件处理器到日志器
        self.logger.addHandler(file_handler)

    def debug(self, message):
        """记录调试信息

        Args:
            message: 日志信息
        """
        self.logger.debug(message)

    def info(self, message):
        """记录一般信息

        Args:
            message: 日志信息
        """
        self.logger.info(message)

    def warning(self, message):
        """记录警告信息

        Args:
            message: 日志信息
        """
        self.logger.warning(message)

    def error(self, message):
        """记录错误信息

        Args:
            message: 日志信息
        """
        self.logger.error(message)

    def critical(self, message):
        """记录严重错误信息

        Args:
            message: 日志信息
        """
        self.logger.critical(message)

    def exception(self, message):
        """记录异常信息

        Args:
            message: 日志信息
        """
        self.logger.exception(message)

    def log(self, level, message):
        """记录指定级别的日志信息

        Args:
            level: 日志级别
            message: 日志信息
        """
        self.logger.log(level, message)

    def start_process(self, process_name):
        """记录流程开始

        Args:
            process_name: 流程名称

        Returns:
            datetime.datetime: 流程开始时间
        """
        start_time = datetime.datetime.now()
        self.info(f"==== 开始流程: {process_name} ====")
        self.info(
            f"开始时间: {start_time.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}"
        )
        return start_time

    def end_process(self, process_name, start_time):
        """记录流程结束

        Args:
            process_name: 流程名称
            start_time: 流程开始时间
        """
        end_time = datetime.datetime.now()
        duration = end_time - start_time
        self.info(
            f"结束时间: {end_time.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}"
        )
        self.info(f"持续时间: {duration.total_seconds():.3f} 秒")
        self.info(f"==== 结束流程: {process_name} ====\n")

    def log_separator(self):
        """记录分隔符"""
        self.info("=" * 80)

    def log_data_info(self, data_name, data):
        """记录数据信息

        Args:
            data_name: 数据名称
            data: 数据对象
        """
        import pandas as pd

        if isinstance(data, pd.DataFrame):
            self.info(f"数据 '{data_name}' 信息:")
            self.info(f"- 行数: {len(data)}")
            self.info(f"- 列数: {len(data.columns)}")
            self.info(f"- 列名: {', '.join(data.columns.tolist())}")
            self.info(f"- 数据类型: {data.dtypes.astype(str).to_dict()}")
            # 记录非空值统计
            non_null_counts = data.notna().sum()
            self.info(f"- 非空值统计: {non_null_counts.to_dict()}")
        elif isinstance(data, list):
            self.info(f"数据 '{data_name}' 信息:")
            self.info(f"- 长度: {len(data)}")
            if len(data) > 0:
                self.info(f"- 第一个元素类型: {type(data[0])}")
                if len(data) <= 5:
                    self.info(f"- 所有元素: {data}")
                else:
                    self.info(f"- 前5个元素: {data[:5]}")
        elif isinstance(data, dict):
            self.info(f"数据 '{data_name}' 信息:")
            self.info(f"- 键数量: {len(data)}")
            self.info(f"- 键列表: {list(data.keys())}")
        else:
            self.info(f"数据 '{data_name}' 信息:")
            self.info(f"- 类型: {type(data)}")
            self.info(f"- 值: {data}")

    def set_log_level(self, level):
        """设置日志级别

        Args:
            level: 日志级别
        """
        self.logger.setLevel(level)
        for handler in self.logger.handlers:
            handler.setLevel(level)
